﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;

namespace TestAppDomain
{
    class Program
    {
        static void Main(string[] args)
        {
            Process(@"c:\temp\new");
            Console.ReadLine();
        }

        public static async void Process(string directory)
        {
            await Task.Run(() => Process2(directory));
        }

        private static void Process2(string directory)
        {
            string[] files = System.IO.Directory.GetFiles(directory, "Sage*.dll");

            foreach (string file in files)
            {
                LoadAndUnloadAppDomain(file);
            }
        }

        private static void LoadAndUnloadAppDomain(string assemblyPath)
        {
            AppDomain myDomain = AppDomain.CreateDomain("MyDomain");
            //Create the loader (a proxy).
            var assemblyLoader = (SimpleAssemblyLoader)myDomain.CreateInstanceAndUnwrap(typeof(SimpleAssemblyLoader).Assembly.FullName, typeof(SimpleAssemblyLoader).FullName);
            //Load an assembly in the LoadFrom context. Note that the Load context will
            //not work unless you correctly set the AppDomain base-dir and private-bin-paths.
            assemblyLoader.LoadFrom(assemblyPath);

            //Do whatever you want to do.

            //Finally unload the AppDomain.
            AppDomain.Unload(myDomain);
        }

        public class SimpleAssemblyLoader : MarshalByRefObject
        {
            public void Load(string path)
            {
                ValidatePath(path);

                Assembly.Load(path);
            }

            public void LoadFrom(string path)
            {
                ValidatePath(path);

                Assembly.LoadFrom(path);
            }

            private void ValidatePath(string path)
            {
                if (path == null) throw new ArgumentNullException("path");
                if (!System.IO.File.Exists(path))
                    throw new ArgumentException(String.Format("path \"{0}\" does not exist", path));
            }
        }
    }
}
